﻿using RunAsManager.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RunAsManager
{
    public partial class RunAsManager : Form
    {
        public RunAsManager()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox1.Text))
            {
                MessageBox.Show("目标不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (string.IsNullOrEmpty(textBox2.Text))
            {
                MessageBox.Show("工作不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (string.IsNullOrEmpty(textBox3.Text))
            {
                MessageBox.Show("用户名不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (string.IsNullOrEmpty(textBox4.Text))
            {
                MessageBox.Show("密码不能为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            var result = saveFile.ShowDialog();
            if(result == DialogResult.OK)
            {
                using (var file = File.Create(saveFile.FileName))
                {
                    var data = Resources.RunAs;

                    file.Write(data, 0, data.Length);

                    string processPath = textBox1.Text.Trim();
                    string workingDirectory = textBox2.Text.Trim();
                    string user = textBox3.Text.Trim();
                    string password = textBox4.Text.Trim();

                    if (checkBox1.Checked)
                    {
                        if(!File.Exists(processPath))
                        {
                            MessageBox.Show("目标文件不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                        using(var desFile = File.OpenRead(processPath))
                        {
                            int currentIndex = 0;
                            int desFileLen = (int)desFile.Length;
                            while(currentIndex < desFileLen)
                            {
                                byte[] buffer = new byte[1024];
                                if(desFileLen - currentIndex < 1024)
                                {
                                    int readSize = desFile.Read(buffer, 0, desFileLen - currentIndex);
                                    file.Write(buffer, 0, readSize);
                                    currentIndex += readSize;
                                }else
                                {
                                    int readSize = desFile.Read(buffer, 0, 1024);
                                    file.Write(buffer, 0, readSize);
                                    currentIndex += readSize;
                                }
                            }
                            file.Write(BitConverter.GetBytes(desFileLen), 0, 4);
                            file.Write(BitConverter.GetBytes(1008611), 0, 4);
                        }
                    }

                    string appPath = $"{processPath}\n{workingDirectory}";
                    byte[] appPathData = Encoding.UTF8.GetBytes(appPath);
                    file.Write(appPathData, 0, appPathData.Length);
                    file.Write(BitConverter.GetBytes(appPathData.Length), 0, 4);

                    byte[] encryptKey = Encoding.UTF8.GetBytes(MD5Encrypt32(appPath));
                    byte[] encrypt = AesEncrypt(Encoding.UTF8.GetBytes($"{user}\n{password}"), encryptKey);
                    file.Write(encrypt, 0, encrypt.Length);
                    file.Write(BitConverter.GetBytes(encrypt.Length), 0, 4);

                    file.Write(BitConverter.GetBytes(10086), 0, 4);
                }
                
                MessageBox.Show("生成成功");
                Path.GetTempPath();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var result = AppPath.ShowDialog(this);
            if(result == DialogResult.OK)
            {
                textBox1.Text = AppPath.FileName;
                textBox2.Text = Path.GetDirectoryName(textBox1.Text);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            var result = WorkDirectory.ShowDialog(this);
            if(result == DialogResult.OK)
            {
                textBox2.Text = WorkDirectory.SelectedPath;
            }
        }

        private void RunAsManager_Load(object sender, EventArgs e)
        {
        }

        public static string MD5Encrypt32(string str)
        {
            MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(str));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));//转化为小写的16进制
            }
            return sBuilder.ToString();
        }

        public static byte[] AesEncrypt(byte[] data, byte[] Key)
        {
            try
            {
                byte[] result;
                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = Key;
                    aesAlg.Mode = CipherMode.ECB;
                    aesAlg.Padding = PaddingMode.PKCS7;
                    using (ICryptoTransform encryptor = aesAlg.CreateEncryptor())
                    {
                        using (MemoryStream msEncrypt = new MemoryStream())
                        {
                            using (CryptoStream csDecrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                            {
                                csDecrypt.Write(data, 0, data.Length);
                            }
                            result = msEncrypt.ToArray();
                        }
                    }

                }
                return result;
            }
            catch
            {
                return null;
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if(checkBox1.Checked)
            {
                textBox2.Text = Environment.SystemDirectory;
            }
        }
    }
}
